<?php namespace xlx;

class OTP {
    public static function worker($addr){
        $socket = \stream_socket_client($addr, $errno, $errstr) or exit($errstr);  
        \stream_set_blocking($socket, false);   
        
        $event = Workerman\Worker::$globalEvent = OTPServer::createEventLoop();
        $event->add($socket, \Workerman\Events\EventInterface::EV_READ, function ($data) {
            echo $data;
        });
        return $event;
    }
    public static function server($addr){ 
        $socket = \stream_socket_server($addr, $errno, $errstr) or exit($errstr);  
        \stream_set_blocking($socket, false);
        
        $event = Workerman\Worker::$globalEvent = OTPServer::createEventLoop();
        $event->add($socket, \Workerman\Events\EventInterface::EV_READ, function ($socket) {
            if($new_socket = @stream_socket_accept($socket, 0, $remote_address)){

            }
        });
        return $event;
    }
    public static function bulidCode($addr){  
        foreach (get_declared_classes() as $composer) { 
            if(substr($composer,0,22)=='ComposerAutoloaderInit'){
                $ref = new \ReflectionClass($composer);
                $file = $ref->getFileName();
                $class = xlx\OTPWorker::class; 
                return "require_once '$file';$composer::getLoader();"; 
            } 
        } 
        throw new Exception("Error Processing Request", 1); 
    }
}

class Super {
    public static function start($arr){
        $addr = 'frame://0.0.0.0:'.\random_int(9999,99999); 
        system(\PHP_BINARY.' -r '.OTP::bulidCode().OTP::class."::server($addr)");
        //php bg.php     [server] 
        //php start.php -[super] -worker

        return 'pid';
    }
}
 
// Actor::start(function(){
//     //tas
// });    
// Actor::super(function(){
//     //zcq
// });




////////////// supervisor //////////////
//监视服务添加一个监视
$void = \xlx\Supervisor::start_child($coid,$index);//启动 
$void = \xlx\Supervisor::delete_child($coid,$index);//停止进程（监视会自动重启）

$void = \xlx\Supervisor::terminate_child($coid,$index);//停止监视（等待自动结束） 
$atom = \xlx\Supervisor::start_link( $CLASS_NAME ,$args);//添加监视
$coid = \xlx\Supervisor::start_link(function($super, $args){
    $super->flag();
    $super->push(function($super){
        $super->flag(); 
        $super->init( \W1::class ); 
    },\Supervisor::class);//永久
    $super->push(function($actor){},\Worker::class/*spawn*/);//默认限时自动终止
    $super->push(function($actor){},\Service::class/*spawn*/);//永久
    $super->push(\W1::class/*start*/); //限时自动终止
    $super->push(\S1::class/*start*/); //永久
    $super->push(\M1::class/*start*/); //永久
    // $flag = [];
    // $child = [
    //     'a'=> function(){ },//默认限时自动终止
    //     'b'=>[\Worker1::class,'start_link'],//限时自动终止
    //     'c'=>[\Serevice1::class,'start_link'],//永久
    // ];
    // return [$child,$flag]; 
},$args);  
class M1 extends Supervisor{
    public function init($super,$args){ 
        $super->flag();
        $super->init( \W1::class );
    }
}

////////////// service //////////////
$atom = \xlx\Service::start_link($CLASS_NAME,$args);//sync //默认永久 
$coid = \xlx\Service::start_link(function($actor,$args){ },$args);//async  //默认永久 
class S1 extends Service{
    public function init($actor,$args){ }
}

///////////// workers /////////////////

$atom = \xlx\Workers::start_link($CLASS_NAME,$args);//sync //限时自动终止
$coid = \xlx\Workers::start_link(function($actor,$args){ },$args);//async //限时自动终止
class W1 extends Workers{ 
    public function init($actor,$args){  }
} 
// class GenServe extends Workers{
//     public function init(){}
//     public function call(){}
//     public function cast(){}
// }

 